package com.game.sec;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.redisson.api.RRateLimiter;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.game.exception.AuthFailException;
import com.game.globalconst.KeyPrefix;
import com.game.globalconst.NoticeKeyConst;
import com.game.utils.IpUtils;
import com.game.utils.Localization;
import com.game.utils.RedissonUtils;

/**
 * 权限拦截
 * 
 * @author ZGame
 *
 *
 */
@Component
public class AuthInterceptor implements HandlerInterceptor {
	@Autowired
	RedissonClient redissonClient;
	@Value("${security.open}")
	private boolean openSecurity;// token和加解密
	@Value("${limiter.open}")
	private boolean openLimiter;// 限流器

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {

		String token = request.getHeader("access_token");
		String uid = request.getHeader("uid");

		if (!openSecurity) {
			return true;
		}

		String clientIp = IpUtils.getClientIp(request);
		String url = request.getRequestURL().toString();

		int index = url.lastIndexOf("?");
		if (index < 0) {
			index = url.length();
		}
		String action = url.substring(url.lastIndexOf("/") + 1, index);
		if (action.equalsIgnoreCase("login")) {
			return true;
		}
		if (!auth(token, clientIp, uid)) {
			// 转发到全局异常 GlobalExceptionHandler 处理
			throw new AuthFailException(Localization.getInstance().get(NoticeKeyConst.TOKEN_VERIFY_FAIL, null), uid);
		}
		return true;
	}

	/**
	 * 鉴权
	 * 
	 * @param token
	 * @param clientIp
	 * @return
	 */
	private boolean auth(String token, String clientIp, String uid) {
		String key = KeyPrefix.AdminRedisPrefix.ADMIN_USER_ID + uid;
		if (!RedissonUtils.isExists(redissonClient, key)) {
			return false;
		}
		String token_redis = RedissonUtils.get(redissonClient, key, String.class);
		JSONObject jsonObject = JSON.parseObject(token_redis);
		String access_token = jsonObject.getString("access_token");
		String ip = jsonObject.getString("ip");
		if (!ip.equals(clientIp)) {
			return false;
		}
		if (!token.equals(access_token)) {
			return false;
		}
		return true;
	}
}
